---
title: FormInput
description: A form input component with built-in label, description, and error handling capabilities for creating accessible, user-friendly forms.
---
import {
  DefaultFormInputVariant,
  RequiredFormInputVariant,
  RequiredWithErrorFormInputVariant,
  OptionalFormInputVariant,
  SuccessFormInputVariant,
  WarningFormInputVariant,
  ErrorFormInputVariant,
  DisabledFormInputVariant,
  DefaultValueFormInputVariant,
  ReadonlyFormInputVariant,
  ComplexFormInputVariant
} from "./form-input.variants"

## Overview

The FormInput component provides a comprehensive form input system that combines labels, descriptions, and validation states. It's designed to create accessible, user-friendly forms with proper labeling, helpful context, and clear validation feedback while maintaining consistency with the design system.

## Usage

```tsx
import { FormInput } from "@unkey/ui";

export default function MyComponent() {
  return (
    <FormInput
      label="Email Address"
      description="We'll use this to send you important updates."
      placeholder="Enter your email"
      required
    />
  );
}
```

## Examples

### Default FormInput
The default FormInput includes a label and optional description text, providing clear context for users.

<DefaultFormInputVariant />

### Required Field
Use the required prop to indicate mandatory fields. This automatically adds a "Required" tag to the label.

<RequiredFormInputVariant />

### Required Field with Error
When a required field has an error, the "Required" tag changes to error styling to draw more attention.

<RequiredWithErrorFormInputVariant />

### Optional Field
Use the optional prop to explicitly indicate non-mandatory fields. This adds an "Optional" tag to the label.

<OptionalFormInputVariant />

### Success State
Indicates successful validation or acceptance of input value. The success icon and text provide positive feedback.

<SuccessFormInputVariant />

### Warning State
Used for potentially problematic inputs that don't prevent form submission. Includes a warning icon and explanatory text.

<WarningFormInputVariant />

### Error State
Shows validation errors or other issues that need user attention. Features prominent error styling and message.

<ErrorFormInputVariant />

### Disabled State
Apply when the field should be non-interactive, such as during form submission or based on other field values.

<DisabledFormInputVariant />

### With Default Value
Pre-populated input with an initial value that users can modify.

<DefaultValueFormInputVariant />

### Read-only State
For displaying non-editable information while maintaining form layout consistency.

<ReadonlyFormInputVariant />

### Complex Usage
Example of a FormInput with multiple props configured for a specific use case.

<ComplexFormInputVariant />

## Features

- **Built-in Labeling**: Automatic label association with proper accessibility
- **Description Support**: Optional helper text for additional context
- **Validation States**: Multiple states (success, warning, error) with appropriate styling
- **Required/Optional Indicators**: Clear visual indicators for field requirements
- **Accessibility**: Full accessibility support with proper ARIA attributes
- **Responsive Design**: Adapts to different screen sizes
- **Dark Mode Support**: Consistent appearance in light and dark themes
- **Customizable**: Extensive styling options through className props

## Props

The FormInput component extends the standard Input component props with additional form-specific properties:

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `label` | `string` | - | The label text to display above the input |
| `description` | `string \| React.ReactNode` | - | Optional helper text displayed below the input |
| `required` | `boolean` | - | Whether the field is required. Adds a "Required" indicator |
| `optional` | `boolean` | - | Whether the field is optional. Adds an "Optional" indicator |
| `error` | `string` | - | Error message to display. Overrides description and applies error styling |
| `variant` | `"default" \| "success" \| "warning" \| "error"` | `"default"` | The variant style to use for the input |
| `leftIcon` | `React.ReactNode` | - | Icon to display on the left side of the input |
| `rightIcon` | `React.ReactNode` | - | Icon to display on the right side of the input |
| `wrapperClassName` | `string` | - | Additional CSS classes for the input wrapper |
| `type` | `string` | `"text"` | The HTML input type (text, email, password, etc.) |
| `placeholder` | `string` | - | Placeholder text displayed when input is empty |
| `value` | `string` | - | The current value of the input |
| `defaultValue` | `string` | - | Default value when uncontrolled |
| `disabled` | `boolean` | - | Whether the input is disabled |
| `readOnly` | `boolean` | - | Whether the input is read-only |
| `name` | `string` | - | Name of the input for form submission |
| `onChange` | `(event: React.ChangeEvent<HTMLInputElement>) => void` | - | Callback triggered when input value changes |
| `onFocus` | `(event: React.FocusEvent<HTMLInputElement>) => void` | - | Callback triggered when input gains focus |
| `onBlur` | `(event: React.FocusEvent<HTMLInputElement>) => void` | - | Callback triggered when input loses focus |
| `className` | `string` | - | Additional CSS classes to apply |
| `id` | `string` | - | Unique identifier for the input. Auto-generated if not provided |

## Variants

### Default
- Standard form input with label and optional description
- Use for most form fields
- Balanced visual weight and accessibility

### Required
- Includes "Required" indicator for mandatory fields
- Use for fields that must be completed
- Clear visual indication of importance

### Optional
- Includes "Optional" indicator for non-mandatory fields
- Use for fields that can be left empty
- Provides clarity in forms with mixed requirements

### Success
- Green styling for positive validation states
- Use for successfully validated inputs
- Encourages positive user feedback

### Warning
- Yellow/orange styling for cautionary states
- Use for inputs that need attention but aren't errors
- Indicates potential issues

### Error
- Red styling for validation errors
- Use for failed validation or critical issues
- Clearly indicates problems that need resolution

## Structure

The FormInput component is composed of:

1. **Label Container** - Contains the label text and required/optional indicators
2. **Input Element** - The actual input field with validation states
3. **Description Text** - Optional helper text below the input
4. **Error Message** - Validation error display when applicable
5. **Status Icons** - Visual indicators for different states

## Styling

The component includes default styling with:

- Consistent spacing and typography from design system
- Color-coded validation states for semantic meaning
- Proper label positioning and association
- Dark mode support with appropriate color schemes
- Focus states for accessibility
- Customizable through className props

### Custom Styling

You can customize the appearance using className props:

```tsx
<FormInput
  label="Custom Input"
  description="Custom description"
  className="custom-form-input-class"
  variant="success"
/>
```

## Accessibility

The FormInput component is built with accessibility in mind:

- **Label Association**: Labels are properly associated with inputs using htmlFor/id
- **Error Announcements**: Error messages are announced to screen readers using role="alert"
- **Required Indicators**: Required fields are marked both visually and via aria-required
- **Helper Text**: Helper text is linked to inputs using aria-describedby
- **Validation States**: Error states are indicated using aria-invalid
- **Screen Reader Support**: Announces validation states and requirements appropriately
- **Keyboard Navigation**: Full keyboard support for all interactions